package main

import (
  "fmt"
  "time"
  //"go-scripts/services"
  "os"
  //"sort"
  //"sort"
  //"go-scripts/common"
  "go-scripts/models"
  "gopkg.in/mgo.v2/bson"
  //"sync"
  "runtime/debug"
  "go-scripts/common"
  "go-scripts/services"
  "sort"
  "sync"
  "gopkg.in/mgo.v2"
)

var model = models.GetModel()
var stockDao *mgo.Collection
var themeDao *mgo.Collection

func init()  {
  var err error
  stockDao, err = model.GetModelCollection("Stock")
  if err != nil {
    panic(err.Error())
  }
  themeDao, err = model.GetModelCollection("Theme")
  if err != nil {
    panic(err.Error())
  }
}

func main() {
  defer func() {
    if err := recover(); err != nil {
      fmt.Println("panic")
      fmt.Println(err)
      debug.PrintStack()
      os.Exit(0)
    }
  }()
  create := os.Args[1]
  //加载redisService
  redisService := services.GetRedisService()
  var err error
  //获取20小时之内的研报id
  now := time.Now()
  near20hourids := redisService.GetTmpInfoIdsByTime(now.Unix() - 20 * 3600, now.Unix())
  //获取这些研报的次数
  near20hourcounts := redisService.GetTmpInfoCountByIds(near20hourids)
  //按照次数排序
  sort.Sort(sort.Reverse(near20hourcounts))
  //获取转载次数最多的前30条的新闻id
  mostCountNews := make(map[string]int)
  //总共100条
  if len(near20hourcounts) > 100 {
    near20hourcounts = near20hourcounts[0:100]
  }
  for i, length := 0, len(near20hourcounts); i < length && i < 30; i ++ {
    mostCountNews[near20hourcounts[i].Element] = 1
  }
  //封装id为ObjectId
  ids := common.ConverId2ObjectId(near20hourcounts, "Element")
  //封装为新闻为map
  newsMap := map[bson.ObjectId]*models.TmpNews{}
  for _,v := range near20hourcounts {
    report := new(models.TmpNews)
    obj := bson.ObjectIdHex(v.Element)
    report.Id = obj
    report.Count = int(v.Score)
    newsMap[obj] = report
  }
  //获取dao
  model := models.GetModel()
  tmpInfoDao, err := model.GetModelCollection("TmpInfo")
  if err != nil {panic(err.Error())}
  //初始化返回值
  tmpInfos := []* models.TmpInfo{}
  stkNames := []string{}
  themeNames := []string{}
  //异步操作
  var wg sync.WaitGroup
  wg.Add(3)
  //查询tmpInfo
  go func() {
    defer wg.Done()
    err := tmpInfoDao.Find(bson.M{
      "_id": bson.M{
        "$in": ids,
      },
    }).All(&tmpInfos)
    if err != nil {
      panic(err)
    }
  }()
  //查询stockName
  go func() {
    defer wg.Done()
    stkKeys := redisService.GetStkKeys()
    eCodes := []string{}
    for _, v := range stkKeys {
      eCodes = append(eCodes, v[4:12])
    }
    stkNames = redisService.GetStockNameByECodes(eCodes)
  }()
  //查询themeName
  go func() {
    defer wg.Done()
    themes := []* models.Theme{}
    err := themeDao.Find(bson.M{}).Select(bson.M{
      "name" : 1,
    }).All(&themes)
    for _, v := range themes {
      themeNames = append(themeNames, v.Name)
    }
    if err != nil {
      panic(err)
    }
  }()
  wg.Wait()
  //begin := time.Now().UnixNano() / 1000000
  //匹配关键字
  for _,v := range tmpInfos {
    wg.Add(2)
    newsMap[v.Id].Title = v.Title
    newsMap[v.Id].Content = v.Content
    newsMap[v.Id].Url = v.Url
    newsMap[v.Id].PublishedAt = v.PublishedAt
    newsMap[v.Id].Source = v.Source
    go func(task string, id bson.ObjectId) {
      defer wg.Done()
      newsMap[id].Stocks = common.MatchKeysFromString(stkNames, task)
    }(v.Content, v.Id)
    go func(task string, id bson.ObjectId) {
      defer wg.Done()
      newsMap[id].Themes = common.MatchKeysFromString(themeNames, task)
    }(v.Content, v.Id)
  }
  wg.Wait()
  effectTopicDao, err := model.GetModelCollection("EffectTopic")
  tmpNewsDao, err := model.GetModelCollection("TmpNews")
  if err!= nil {
    panic(err.Error())
  }

  rids := []interface{}{}
  for k,v := range newsMap {
    v.Themes = filterForce(v.Themes)
    v.Stocks = filterForce(v.Stocks)
    stocksLen := len(v.Stocks)
    themesLen := len(v.Themes)
    force := getForce(v.Stocks, v.Themes)
    v.Status = 0
    if create == "create" && mostCountNews[k.Hex()] == 1 && (stocksLen + themesLen) > 0 {
    	fmt.Println(k, len(v.Stocks), len(v.Themes), v.Title, v.Count, mostCountNews[k.Hex()] == 1)
      //创建主题
      err := common.CreateTopInfoTopic(v.Title, k.Hex(), force, []string{}, "tmpInfo", "", effectTopicDao)
			if err != nil {
				common.GetLogger().Error(err.Error())
			} else {
      	rids = append(rids, k.Hex())
				v.Status = 1 //保存创建了主题的rid
      	redisService.SaveTmpInfoRids(rids)
			}
    }
    //将股票和题材的iCode和name拼在一起
    v.Stocks = transStocks(v.Stocks)
    v.Themes = transTheme(v.Themes)
    tmpNewsDao.Insert(v)
  }
}
//将股票名和iCode合起来
func transStocks(stocks []string) []string {
  ret := []string{}
  if len(stocks) == 0 {
    return ret
  }
  stocksMap := []map[string]string{}
  stockDao.Find(bson.M{
    "name": bson.M{
      "$in": stocks,
    },
  }).All(&stocksMap)
  for _, v := range stocksMap {
    ret = append(ret, v["iCode"] + "," + v["name"])
  }
  return ret
}
//将题材名和iCode合起来
func transTheme(themes []string) []string {
  ret := []string{}
  if len(themes) == 0 {
    return ret
  }
  themesMap := []map[string]string{}
  themeDao.Find(bson.M{
    "name": bson.M{
      "$in": themes,
    },
  }).All(&themesMap)
  for _, v := range themesMap {
    ret = append(ret, v["iCode"] + "," + v["name"])
  }
  return ret
}

var BlackListMap map[string]int = map[string]int{
  "综合": 1,
  "互联网": 1,
  "彩票": 1,
  "迪士尼": 1,
  "H股": 1,
  "大盘": 1,
  "中盘": 1,
  "小盘": 1,
  "大智慧": 1,
  "同花顺": 1,
  "东方财富": 1,
  "星期六": 1,
  "国新能源": 1,
  "二三四五": 1,
  "长白山": 1,
  "张家界": 1,
}

func filterForce(forces []string) []string {
  newForces := []string{}
  for _, v := range forces {
    if value := BlackListMap[v]; value != 1 {
      newForces = append(newForces, v)
    }
  }
  return newForces
}

func getForce(stocks, themes []string) []string {
  force := []string{}
  for _, v := range stocks {
    force = append(force, v)
  }
  for _, v := range themes {
    force = append(force, v)
  }
  if len(force) > 6 {
    return force[0:6]
  }
  return force
}